<template>
  <div class="chart-wrapper">
    <h2>{{ title }}</h2>
    <div :id="chartId" class="chart" :style="{ width: chartConfig.width + 'px', height: chartConfig.height + 'px' }"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'PieChart',
  props: {
    /**
     * 图表标题
     * @example '销售渠道分布'
     */
    title: {
      type: String,
      default: '',
    },

    /**
     * 饼图数据
     * @description 包含名称和值的数据数组
     * @example [{ name: '类别1', value: 100 }]
     */
    data: {
      type: Array,
      required: true,
    },

    /**
     * 图表配置项
     * @description 图表的详细配置，包括图例、标签等
     */
    chartConfig: {
      type: Object,
      default: () => ({
        width: 400, // 增加宽度以适应图例
        height: 250,
        // 图例配置
        legend: {
          show: true,
          orient: 'vertical',
          right: 0, // 调整图例位置
          top: 'middle',
          textStyle: {
            color: '#333',
            fontSize: 12,
          },
          formatter: name => name,
        },
        // 提示框配置
        tooltip: {
          show: true,
          trigger: 'item',
          formatter: '{b}: {c} ({d}%)',
        },
        // 系列配置
        series: {
          // 饼图类型配置
          type: 'pie',
          radius: '60%',
          center: ['40%', '50%'], // 将饼图中心向左移动
          // 颜色配置
          colors: ['#ee6666', '#5470c6', '#91cc75', '#fac858', '#73c0de'],
          // 图形样式
          itemStyle: {
            borderRadius: 10,
            borderColor: '#fff',
            borderWidth: 2,
          },
          // 标签配置
          label: {
            show: true,
            formatter: '{b}\n{c}\n{d}%',
            position: 'outside',
            textStyle: {
              fontSize: 14,
            },
          },
          // 标签引导线
          labelLine: {
            show: true,
            length: 5,
            length2: 5,
            smooth: true,
          },
          // 高亮样式
          emphasis: {
            scale: true,
            scaleSize: 10,
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },
          // 动画配置
          animation: true,
          animationDuration: 1000,
          animationEasing: 'cubicOut',
        },
      }),
    },

    /**
     * PPT导出配置
     * @description PPT导出时的样式和布局配置
     */
    pptOptions: {
      type: Object,
      default: () => ({
        // 图表位置和大小
        position: {
          x: 5.5,
          y: 1.7,
          w: 4.5,
          h: 3.5,
        },
        // 标题配置
        title: {
          x: 5.5,
          y: 1.2,
          fontSize: 16,
          color: '363636',
          bold: true,
        },
        // 图表配置
        chart: {
          showLegend: true,
          legendPos: 'r',
          showValue: true,
          dataLabelPosition: 'bestFit',
          dataLabelFormatCode: '0.0"%"',
          showLeaderLines: true,
          showLabel: true,
          showPercent: true,
          showTitle: false,
          // 阴影效果
          shadow: {
            type: 'outer',
            blur: 10,
            offset: 5,
            angle: 45,
            color: '000000',
            opacity: 0.3,
          },
        },
      }),
    },
  },

  data() {
    return {
      // echarts实例
      chart: null,
      // 图表唯一标识
      chartId: Math.random().toString(36).substring(2, 15),
    };
  },

  methods: {
    /**
     * 初始化图表
     * @description 创建echarts实例并首次渲染
     */
    initChart() {
      const chartDom = document.getElementById(this.chartId);
      if (!chartDom) return;

      this.chart = echarts.init(chartDom);
      this.updateChart();
    },

    /**
     * 更新图表数据和配置
     * @description 根据props更新图表的数据和配置项
     */
    updateChart() {
      if (!this.chart) return;

      const option = {
        legend: this.chartConfig.legend,
        tooltip: this.chartConfig.tooltip,
        series: [
          {
            ...this.chartConfig.series,
            data: this.data.map((item, index) => ({
              ...item,
              itemStyle: {
                ...this.chartConfig.series.itemStyle,
                color: this.chartConfig.series.colors[index % this.chartConfig.series.colors.length],
              },
            })),
          },
        ],
      };

      this.chart.setOption(option);
    },

    /**
     * 调整图表大小
     * @description 在容器大小变化时自动调整图表大小
     */
    resizeChart() {
      this.chart && this.chart.resize();
    },

    /**
     * 导出为PPT
     * @description 将图表导出为PPT格式
     * @param {Object} pptx pptxgen实例
     * @param {Object} slide 当前幻灯片实例
     */
    exportToPPT(pptx, slide) {
      // 添加图表标题
      slide.addText(this.title, {
        x: this.pptOptions.title.x,
        y: this.pptOptions.title.y,
        fontSize: this.pptOptions.title.fontSize,
        color: this.pptOptions.title.color,
        bold: this.pptOptions.title.bold,
      });

      // 添加饼图
      slide.addChart(
        pptx.ChartType.pie,
        [
          {
            name: '分布占比',
            labels: this.data.map(item => item.name),
            values: this.data.map(item => item.value),
          },
        ],
        {
          x: this.pptOptions.position.x,
          y: this.pptOptions.position.y,
          w: this.pptOptions.position.w,
          h: this.pptOptions.position.h,
          chartArea: this.pptOptions.chart.chartArea,
          chartColors: this.chartConfig.series.colors.map(color => color.replace('#', '')),
          showLegend: this.pptOptions.chart.showLegend,
          legendPos: this.pptOptions.chart.legendPos,
          dataLabelFontSize: this.pptOptions.chart.dataLabelFontSize,
          showValue: this.pptOptions.chart.showValue,
          dataLabelPosition: this.pptOptions.chart.dataLabelPosition,
          dataLabelFormatCode: this.pptOptions.chart.dataLabelFormatCode,
          showLeaderLines: this.pptOptions.chart.showLeaderLines,
          showLabel: this.pptOptions.chart.showLabel,
          showPercent: this.pptOptions.chart.showPercent,
          showTitle: this.pptOptions.chart.showTitle,
          shadow: this.pptOptions.chart.shadow,
        }
      );
    },
  },

  watch: {
    /**
     * 监听数据变化
     * @description 当数据变化时自动更新图表
     */
    data: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
    chartConfig: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
  },

  mounted() {
    this.$nextTick(() => {
      this.initChart();
      window.addEventListener('resize', this.resizeChart);
    });
  },

  beforeDestroy() {
    window.removeEventListener('resize', this.resizeChart);
    this.chart && this.chart.dispose();
    this.chart = null;
  },
};
</script>

<style lang="less" scoped></style>
